#include "bsp_ble.h"

/**
 * @brief  Ble tx pin, rx pin, rde pin init.
 * @param  None.
 * @return None.
 * @author bagy
 * @date   2024/08/08
 * @note   None.
*/
static void bsp_ble_gpio_init(void)
{
    gpio_af_set(BLE_GPIO_PORT, GPIO_AF_8, BLE_TX_PIN);
    gpio_af_set(BLE_GPIO_PORT, GPIO_AF_8, BLE_RX_PIN);

    gpio_mode_set(BLE_GPIO_PORT, BLE_TX_PIN_MODE, BLE_TX_PIN_PUPD, BLE_TX_PIN);
    gpio_output_options_set(BLE_GPIO_PORT, BLE_TX_PIN_OTYPE, BLE_TX_PIN_SPD, BLE_TX_PIN);

    gpio_mode_set(BLE_GPIO_PORT, BLE_RX_PIN_MODE, BLE_RX_PIN_PUPD, BLE_RX_PIN);
    gpio_output_options_set(BLE_GPIO_PORT, BLE_RX_PIN_OTYPE, BLE_RX_PIN_SPD, BLE_RX_PIN);

    /*!< Ble mode pin config */
    gpio_mode_set(BLE_FUNC_GPIO_PORT, BLE_MOD_PIN_MODE, BLE_MOD_PIN_PUPD, BLE_MOD_PIN);
    gpio_output_options_set(BLE_FUNC_GPIO_PORT, BLE_MOD_PIN_OTYPE, BLE_MOD_PIN_SPD, BLE_MOD_PIN);

    /*!< Ble mode fb pin config */
    gpio_mode_set(BLE_FUNC_GPIO_PORT, BLE_FB_PIN_MODE, BLE_FB_PIN_PUPD, BLE_FB_PIN);
    gpio_output_options_set(BLE_FUNC_GPIO_PORT, BLE_FB_PIN_OTYPE, BLE_FB_PIN_SPD, BLE_FB_PIN);
    
    /*!< Ble wake up pin config */
    gpio_mode_set(BLE_FUNC_GPIO_PORT, BLE_WKUP_PIN_MODE, BLE_WKUP_PIN_PUPD, BLE_WKUP_PIN);
    gpio_output_options_set(BLE_FUNC_GPIO_PORT, BLE_WKUP_PIN_OTYPE, BLE_WKUP_PIN_SPD, BLE_WKUP_PIN);

    log_i("<%s> ble gpio config complete.\r\n", __FUNCTION__);
}

/**
 * @brief  Configuring ble serial port interrupt priority.
 * @param  None.
 * @return None.
 * @author bagy
 * @date   2024/08/08
 * @note   None.
*/
static void bsp_ble_nvic_init(void)
{
    nvic_irq_enable(BLE_UART_IRQn, BLE_UART_INT_PRO, 0);

    log_i("<%s> ble nvic config complete. pro:%d.\r\n",  __FUNCTION__, BLE_UART_INT_PRO);
}

/**
 * @brief  Configure serial port parameters, 8, N, 1.
 * @param  None.
 * @return None.
 * @author bagy
 * @date   2024/08/08
 * @note   Enable serial port idle interrupt, receive interrupt.
*/
static void bsp_ble_uart_init(void)
{
    usart_deinit(BLE_UART);

    usart_baudrate_set(BLE_UART, BLE_UART_BAUDRATE);
    usart_parity_config(BLE_UART, USART_PM_NONE);
    usart_word_length_set(BLE_UART, USART_WL_8BIT);
    usart_stop_bit_set(BLE_UART, USART_STB_1BIT);

    usart_receive_config(BLE_UART, USART_RECEIVE_ENABLE);
    usart_transmit_config(BLE_UART, USART_TRANSMIT_ENABLE);
    usart_dma_receive_config(BLE_UART, USART_RECEIVE_DMA_ENABLE);

    usart_interrupt_enable(BLE_UART, USART_INT_RBNE);
    usart_interrupt_enable(BLE_UART, USART_INT_IDLE);

    usart_enable(BLE_UART);

    log_i("<%s> ble uart param config complete. baudrate:%d.\r\n",  __FUNCTION__, BLE_UART_BAUDRATE);
}

/**
 * @brief  Serial port send data.
 * @param  buff:data being sent.
 * @param  len :Length of buff sent, uint: bytes
 * @return None.
 * @author bagy
 * @date   2024/08/08
 * @note   None.
*/
void bsp_ble_sendbuff(uint8_t *buff, uint32_t len)
{
    ES_ASSERT(buff != NULL);
    ES_ASSERT(len > 0);

    for(uint32_t i = 0; i < len; i++)
    {
        while(RESET == usart_flag_get(BLE_UART, USART_FLAG_TBE));
        usart_data_transmit(BLE_UART, *buff);
        buff++;
    }
    while(RESET == usart_flag_get(BLE_UART, USART_FLAG_TC));
}

/**
 * @brief  Initializing the ble necessary module.
 * @param  None.
 * @return None.
 * @author bagy
 * @date   2024/08/08
 * @note   None.
*/
void bsp_ble_config(void)
{
    bsp_ble_gpio_init();
    bsp_ble_nvic_init();
    bsp_ble_uart_init();

    log_i("<%s> ble gpio & nvic & uart config complete.\r\n",  __FUNCTION__);
}

